package com.example.teemor.es_demo.service;

import com.example.teemor.es_demo.entity.Order;
import com.example.teemor.es_demo.entity.OrderItem;
import com.example.teemor.es_demo.entity.User;
import com.example.teemor.es_demo.entity.ProductMySQL;
import com.example.teemor.es_demo.repository.jpa.OrderRepository;
import com.example.teemor.es_demo.repository.jpa.UserRepository;
import com.example.teemor.es_demo.repository.jpa.ProductMySQLRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

@Slf4j
@Service
@RequiredArgsConstructor
public class OrderService {

    private final OrderRepository orderRepository;
    private final UserRepository userRepository;
    private final ProductMySQLRepository productRepository;
    private final UserBehaviorService userBehaviorService;

    /**
     * 创建订单
     */
    @Transactional
    public Order createOrder(Long userId, List<OrderItem> orderItems) {
        log.info("Creating order for user: {}", userId);
        
        // 获取用户
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在: " + userId));
        
        // 创建订单
        Order order = new Order();
        order.setUser(user);
        order.setOrderNo(generateOrderNo());
        order.setStatus(Order.OrderStatus.PENDING);
        
        // 计算订单总金额并设置订单项
        BigDecimal totalAmount = BigDecimal.ZERO;
        for (OrderItem item : orderItems) {
            // 验证商品存在
            ProductMySQL product = productRepository.findById(item.getProduct().getId())
                    .orElseThrow(() -> new RuntimeException("商品不存在: " + item.getProduct().getId()));
            
            // 检查库存
            if (product.getStock() < item.getQuantity()) {
                throw new RuntimeException("商品库存不足: " + product.getTitle());
            }
            
            // 设置商品信息和价格
            item.setProduct(product);
            item.setPrice(product.getPrice());
            item.setTotalPrice(item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())));
            item.setOrder(order);
            
            totalAmount = totalAmount.add(item.getTotalPrice());
        }
        
        order.setOrderItems(orderItems);
        order.setTotalAmount(totalAmount);
        
        Order savedOrder = orderRepository.save(order);
        
        // 记录用户行为
        userBehaviorService.recordPurchaseBehavior(userId, orderItems);
        
        return savedOrder;
    }

    /**
     * 根据ID获取订单
     */
    public Optional<Order> getOrderById(Long id) {
        return orderRepository.findById(id);
    }

    /**
     * 根据订单号获取订单
     */
    public Optional<Order> getOrderByOrderNo(String orderNo) {
        return orderRepository.findByOrderNo(orderNo);
    }

    /**
     * 获取用户订单列表
     */
    public Page<Order> getUserOrders(Long userId, Pageable pageable) {
        return orderRepository.findByUserIdOrderByCreatedAtDesc(userId, pageable);
    }

    /**
     * 获取用户指定状态的订单
     */
    public List<Order> getUserOrdersByStatus(Long userId, Order.OrderStatus status) {
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new RuntimeException("用户不存在: " + userId));
        return orderRepository.findByUserAndStatus(user, status);
    }

    /**
     * 获取所有订单列表（分页）
     */
    public Page<Order> getAllOrders(Pageable pageable) {
        return orderRepository.findAll(pageable);
    }

    /**
     * 更新订单状态
     */
    @Transactional
    public Order updateOrderStatus(Long orderId, Order.OrderStatus status) {
        log.info("Updating order status: {} to {}", orderId, status);
        
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));
        
        Order.OrderStatus oldStatus = order.getStatus();
        order.setStatus(status);
        
        // 如果订单状态变为已支付，需要减少库存
        if (status == Order.OrderStatus.PAID && oldStatus != Order.OrderStatus.PAID) {
            updateProductStock(order);
        }
        
        return orderRepository.save(order);
    }

    /**
     * 取消订单
     */
    @Transactional
    public Order cancelOrder(Long orderId) {
        log.info("Cancelling order: {}", orderId);
        
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));
        
        if (order.getStatus() == Order.OrderStatus.PAID || 
            order.getStatus() == Order.OrderStatus.SHIPPED || 
            order.getStatus() == Order.OrderStatus.DELIVERED) {
            throw new RuntimeException("订单状态不允许取消");
        }
        
        order.setStatus(Order.OrderStatus.CANCELLED);
        return orderRepository.save(order);
    }

    /**
     * 删除订单
     */
    @Transactional
    public void deleteOrder(Long orderId) {
        log.info("Deleting order: {}", orderId);
        
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new RuntimeException("订单不存在: " + orderId));
        
        if (order.getStatus() != Order.OrderStatus.CANCELLED) {
            throw new RuntimeException("只能删除已取消的订单");
        }
        
        orderRepository.deleteById(orderId);
    }

    /**
     * 获取订单统计信息
     */
    public OrderStats getOrderStats() {
        Long totalOrders = orderRepository.count();
        BigDecimal totalRevenue = orderRepository.sumTotalAmountByStatus(Order.OrderStatus.PAID);
        Long todayOrders = orderRepository.countTodayOrders();
        BigDecimal todayAmount = orderRepository.sumTodayOrderAmount(Order.OrderStatus.PAID);
        
        return OrderStats.builder()
                .totalOrders(totalOrders != null ? totalOrders : 0L)
                .totalRevenue(totalRevenue != null ? totalRevenue : BigDecimal.ZERO)
                .todayOrderCount(todayOrders != null ? todayOrders : 0L)
                .todayOrderAmount(todayAmount != null ? todayAmount : BigDecimal.ZERO)
                .build();
    }

    /**
     * 获取用户订单统计
     */
    public UserOrderStats getUserOrderStats(Long userId) {
        Long totalOrders = orderRepository.countByUserId(userId);
        BigDecimal totalAmount = orderRepository.sumTotalAmountByUserIdAndStatus(userId, Order.OrderStatus.PAID);
        
        return UserOrderStats.builder()
                .totalOrders(totalOrders != null ? totalOrders : 0L)
                .totalAmount(totalAmount != null ? totalAmount : BigDecimal.ZERO)
                .build();
    }

    /**
     * 获取订单趋势数据
     */
    public List<Map<String, Object>> getOrderTrend(LocalDateTime start, LocalDateTime end) {
        return orderRepository.getOrderTrend(start, end);
    }

    /**
     * 获取收入趋势数据
     */
    public List<Map<String, Object>> getRevenueTrend(LocalDateTime start, LocalDateTime end) {
        return orderRepository.getRevenueTrend(start, end);
    }

    /**
     * 获取指定时间范围内的订单
     */
    public List<Order> getOrdersBetweenDates(LocalDateTime startTime, LocalDateTime endTime) {
        return orderRepository.findOrdersBetweenDates(startTime, endTime);
    }

    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
        return "ORD" + timestamp + uuid;
    }

    /**
     * 更新商品库存
     */
    private void updateProductStock(Order order) {
        for (OrderItem item : order.getOrderItems()) {
            ProductMySQL product = item.getProduct();
            int newStock = product.getStock() - item.getQuantity();
            if (newStock < 0) {
                throw new RuntimeException("商品库存不足: " + product.getTitle());
            }
            product.setStock(newStock);
            productRepository.save(product);
        }
    }

    // 内部类用于统计信息
    @lombok.Builder
    @lombok.Data
    public static class OrderStats {
        private Long totalOrders;
        private BigDecimal totalRevenue;
        private Long todayOrderCount;
        private BigDecimal todayOrderAmount;
    }

    @lombok.Builder
    @lombok.Data
    public static class UserOrderStats {
        private Long totalOrders;
        private BigDecimal totalAmount;
    }
}